﻿#define V1
//#define V2
//#define V3


using System;


///////////////////////////////////////////////////////////////////////////////


namespace PassingValueTypesByReference {
	public sealed class Program {
#if V1
		public static void Main() {
			Int32 x;               // x is uninitialized
			SetVal(out x);         // x doesn’t have to be initialized.
			Console.WriteLine(x);  // Displays "10"
		}

		private static void SetVal(out Int32 v) {
			v = 10;  // This method must initialize v.
		}
#endif
#if V2
		public static void Main() {
			Int32 x = 5;         // x is initialized
			AddVal(ref x);        // x must be initialized.
			Console.WriteLine(x); // Displays "15"
		}

		private static void AddVal(ref Int32 v) {
			v += 10;  // This method can use the initialized value in v.
		}
#endif
#if V3
		public static void Main() {
			Int32 x;              // x is not initialized.

			// The following line fails to compile, producing 
			// error CS0165: Use of unassigned local variable 'x'.
			AddVal(ref x);

			Console.WriteLine(x);
		}

		private static void AddVal(ref Int32 v) {
			v += 10;  // This method can use the initialized value in v.
		}
#endif

		public static void Swap(ref Object a, ref Object b) {
			Object t = b;
			b = a;
			a = t;
		}

#if true
		public static void SomeMethod() {
			String s1 = "Jeffrey";
			String s2 = "Richter";
			Swap(ref s1, ref s2);
			Console.WriteLine(s1);  // Displays "Richter"
			Console.WriteLine(s2);  // Displays "Jeffrey"
		}
#endif

		public static void SomeMethod2() {
			String s1 = "Jeffrey";
			String s2 = "Richter";
		
			// Variables that are passed by reference 
			// must match what the method expects.
			Object o1 = s1, o2 = s2;
			Swap(ref o1, ref o2);

			// Now cast the objects back to strings.
			s1 = (String) o1;
			s2	= (String) o2;
   
			Console.WriteLine(s1);  // Displays "Richter"
			Console.WriteLine(s2);  // Displays "Jeffrey"
		}

		public static void Swap<T>(ref T a, ref T b) {
			T t = b;
			b = a;
			a = t;
		}
	}
}


///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////


public sealed class Point {
   static void Add(Point p) { /* ... */ }
   static void Add(ref Point p) { /* ... */ }

	// 'Add' cannot define overloaded methods that differ only on ref and out
	// static void Add(out Point p) { /* ... */ }
}


///////////////////////////////////////////////////////////////////////////////



////////////////////////////// End of File ////////////////////////////////////
